//package com.ruoyi.workflow.service.impl;
//
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.ruoyi.business.domain.ServiceItem;
//import com.ruoyi.business.service.IServiceItemService;
//import com.ruoyi.common.core.domain.entity.SysUser;
//import com.ruoyi.common.exception.ServiceException;
//import com.ruoyi.common.utils.SecurityUtils;
//import com.ruoyi.system.service.ISysUserService;
//import com.ruoyi.workflow.domain.CarPackageAudit;
//import com.ruoyi.workflow.mapper.CarPackageAuditMapper;
//import com.ruoyi.workflow.service.IBpmnNodeService;
//import com.ruoyi.workflow.service.ICarPackageAuditService;
//import org.activiti.bpmn.model.BpmnModel;
//import org.activiti.engine.HistoryService;
//import org.activiti.engine.RepositoryService;
//import org.activiti.engine.RuntimeService;
//import org.activiti.engine.TaskService;
//import org.activiti.engine.history.HistoricActivityInstance;
//import org.activiti.engine.runtime.ProcessInstance;
//import org.activiti.engine.task.Task;
//import org.activiti.image.ProcessDiagramGenerator;
//import org.springframework.beans.factory.annotation.Autowired;
//
//import java.io.InputStream;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.List;
//import java.util.stream.Collectors;
//
//public class Aa11 extends ServiceImpl<CarPackageAuditMapper, CarPackageAudit> implements ICarPackageAuditService {
//
//    @Autowired
//    private IServiceItemService serviceItemService;
//    @Autowired
//    private RuntimeService runtimeService;
//    @Autowired
//    private TaskService taskService;
//    @Autowired
//    private ISysUserService userService;
//    @Autowired
//    private IBpmnNodeService bpmnNodeService;
//    @Autowired
//    private RepositoryService repositoryService;
//    @Autowired
//    private HistoryService historyService;
//    @Autowired
//    private ProcessDiagramGenerator processDiagramGenerator;
//
//    @Override
//    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit) {
//        return null;
//    }
//
//    @Override
//    public void audit(Long serviceItemId, String info) {
//        // 1. 根据服务项 id 查询服务项对象
//        ServiceItem serviceItem = serviceItemService.get(serviceItemId);
//        // 2. 校验审核合法性(是套餐 && 状态为初始化), 提示当前无法审核
//        if (!ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())) {
//            throw new ServiceException("无效操作");
//        }
//        // 3. 修改服务项状态为审核中
//        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
//        // 4. 创建一条审核记录信息, 设置相关数据
//        CarPackageAudit audit = new CarPackageAudit();
//        // 4.1 将服务项信息转换为 json 字符串设置到审核记录中
//        audit.setServiceItemId(serviceItemId);
//        audit.setServiceItemInfo(serviceItem.getInfo());
//        audit.setServiceItemName(serviceItem.getName());
//        audit.setServiceItemPrice(serviceItem.getDiscountPrice());
//        // 4.2 获取到当前登录用户, 将其 id 设置到审核记录中
//        audit.setCreatorId(SecurityUtils.getUserId() + "");
//        // 4.3 将审核状态设置为进行中
//        audit.setStatus(CarPackageAudit.PACKAGE_AUDIT_STATUS_PENDING);
//        // 4.4 保存审核记录信息
//        super.save(audit);
//
//        // 5. 构建流程变量(BusinessKey/金额/审核人员)
//        HashMap<String, Object> map = new HashMap<>();
//        // 5.1 BusinessKey = 审核记录的 id
//        String businessKey = audit.getId() + "";
//        // 5.2 金额 = 服务项的折扣金额
//        map.put("money", serviceItem.getDiscountPrice().longValue() + "");
//        // 5.3 TODO 审核人员 = 查询当前流程实例对应的节点列表, 获取到每一个节点的人员列表
//
//        // 6. 基于流程定义 Key 开启流程实例, 得到流程实例对象
//        ProcessInstance instance = runtimeService.startProcessInstanceByKey(
//                CarPackageAudit.CAR_PACKAGE_DEFINITION_KEY,
//                businessKey,
//                map
//        );
//        // 6.1 将流程实例 id 设置到审核记录中
//        audit.setInstanceId(instance.getId());
//        // 6.2 更新审核记录表
//        super.updateById(audit);
//        // 7. 设置当前任务的候选人, 基于流程实例查询到当前进行中的任务(list/singleResult) => 任务 API TaskService
//        Task currentTask = taskService.createTaskQuery()
//                .processInstanceId(instance.getId())
//                .singleResult();
//        // 7.1 基于任务 key 去查询候选人列表
//        List<SysUser> userList = bpmnNodeService.selectUsersByNodeKey(currentTask.getTaskDefinitionKey());
//        // 7.2 调用 activiti 的 api 为指定任务设置候选人
//        for (SysUser user : userList) {
//            taskService.addCandidateUser(currentTask.getId(), user.getUserName());
//        }
//    }
//
//    @Override
//    public InputStream getProcessingImage(String instanceId) {
//        // 1. 基于流程实例 id 查询流程实例对象
//        ProcessInstance instance = runtimeService.createProcessInstanceQuery()
//                .processInstanceId(instanceId)
//                .singleResult();
//        if (instance == null) {
//            throw new ServiceException("流程已结束");
//        }
//        // 2. 基于仓库 service 查询 bpmnModel 对象
//        BpmnModel bpmnModel = repositoryService.getBpmnModel(instance.getProcessDefinitionId());
//        // 3. 获取需要高亮的活动 id list
//        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
//                .processInstanceId(instanceId)
//                .list();
//        // 将活动实例对象转换为活动 id
//        // 将 Stream 收集为一个 List 集合
//        List<String> collect = list.stream()
//                .map(HistoricActivityInstance::getActivityId)
//                .collect(Collectors.toList());
//
//        // 模型对象 == 流程文件转换的对象
//        // 需要高亮的活动 id 集合, 活动 == 所有运行的节点
//        // 需要高亮的引导线 id 集合
//        return processDiagramGenerator.generateDiagram(
//                bpmnModel,
//                collect,
//                Collections.emptyList(),
//                "宋体",
//                "宋体",
//                "宋体"
//                );
//    }
//
//    @Override
//    public void cancel(Long id, String reason) {
//        // 1. 基于审核记录id查询审核记录对象
//        // 当前审核记录必须是进行中才可以撤销申请
//        // 2. 基于审核记录中的服务项 id, 将服务项状态修改为初始化
//        // 3. 将审核记录的状态修改为撤销申请
//        // 4. 调用 activiti 的 api 删除流程实例, 提供删除理由
//    }
//
//    @Override
//    public void doAudit(Long id, String taskId, boolean result, String info) {
//        // 1. 根据审核记录 id 获取记录对象, 并判断状态为审核中才允许审核
//        // 2. 基于当前用户名作为候选人/负责人条件查询任务信息, 如果查询不到则提示非法访问
//        // 3. 设置流程变量(审核结果)
//        // 4. 领取任务/完成任务/添加批注
//        // 5. 基于流程实例查询下一个进行中的任务, 根据是有下一个任务判断流程是否结束
//        // 6. 有下一个任务
//        // 6.1. 判断当前审核结果是通过还是拒绝
//        // 6.2. 如果是审核通过, 基于任务 key 查询候选人列表
//        // 6.2.1. 为下一个任务设置候选人
//        // 6.3. 如果是审核拒绝, 为任务 设置 候选人 为 发起人
//        // 6.3.1. 通过审核记录对象的创建 id, 查询创建人用户对象
//        // 6.3.2. 将创建人对象的用户名设置到任务的候选人
//        // 6.3.3. 更新服务项的状态为重新调整
//    }
//}
